package com.zs.games.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zs.games.resultTool.ResultCodeEnum;
import com.zs.games.entity.*;
import com.zs.games.enums.SourceTypeEnum;
import com.zs.games.exception.APIException;
import com.zs.games.mapper.*;
import com.zs.games.param.PageQuery;
import com.zs.games.param.UserCommentNewParam;
import com.zs.games.service.GameNewsService;
import com.zs.games.utils.DateUtil;
import com.zs.games.utils.JwtTokenUtils;
import com.zs.games.vo.GameNewVo;
import com.zs.games.vo.LoginUserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class GameNewsServiceImpl extends ServiceImpl<GameNewsMapper, GameNews> implements GameNewsService {

    @Autowired
    private UserCollectNewsMapper userCollectNewsMapper;
    @Autowired
    private UserCommentMapper userCommentMapper;
    @Autowired
    private UserPraiseMapper userNewPraiseMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Override
    public IPage<GameNewVo> getPageNews(PageQuery param) {
        LoginUserVo userInfo = JwtTokenUtils.getUserInfo();
        Page<GameNewVo> page = new Page<>(param.getPageNumber(), param.getPageSize());
        IPage<GameNewVo> gameNewsPage = baseMapper.findGameNewPage(page, userInfo == null ? null : userInfo.getUserId());
        for (GameNewVo record : gameNewsPage.getRecords()) {
            getGameNewVo(record);
        }
        return gameNewsPage;
    }

    private GameNewVo getGameNewVo(GameNewVo gameNewVo){
        UserInfo userInfo = userInfoMapper.selectById(gameNewVo.getCreateUserId());
        if (userInfo != null) {
            gameNewVo.setCreateUserNickName(userInfo.getNickName());
        }
        LoginUserVo loginUserVo = JwtTokenUtils.getUserInfo();
        gameNewVo.setDateStr(DateUtil.getDateStr(gameNewVo.getCreateTime(), DateUtil.FORMAT_YYYY_MM_DD));
        gameNewVo.setUserNewCommentList(userCommentMapper.getUserCommentList(gameNewVo.getNewsId(),SourceTypeEnum.NEWS.getValue()));
        if (loginUserVo != null){
            gameNewVo.setCollectFlag(userCollectNewsMapper.selectCount(
                    new QueryWrapper<UserCollectNews>().lambda().eq(UserCollectNews::getUserId, loginUserVo.getUserId()).eq(UserCollectNews::getNewId,gameNewVo.getNewsId())) > 0);
            gameNewVo.setPraiseFlag(userNewPraiseMapper.selectCount(
                    new QueryWrapper<UserPraise>().lambda().eq(UserPraise::getUserId, loginUserVo.getUserId()).eq(UserPraise::getSourceId,gameNewVo.getNewsId()).eq(UserPraise::getSourceType,SourceTypeEnum.NEWS.getValue())) > 0);

        }
        return gameNewVo;
    }

    @Override
    public GameNewVo getGameNewsById(Integer newsId) {
        GameNews gameNews = getById(newsId);
        if (gameNews == null) {
            return new GameNewVo();
        }
        GameNewVo gameNewVo = new GameNewVo();
        BeanUtils.copyProperties(gameNews, gameNewVo);
        return getGameNewVo(gameNewVo);
    }

    @Override
    public Boolean createGameNews(GameNews gameNews) {
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        gameNews.setCreateUserId(userInfo.getUserId());
        gameNews.setCreateTime(new Date());
        return save(gameNews);
    }

    @Override
    public Boolean updateGameNews(GameNews gameNews) {
        return updateById(gameNews);
    }

    @Override
    public Boolean deleteGameNews(Integer newsId) {
        return removeById(newsId);
    }

    @Override
    public Boolean praiseGameNews(Integer newsId) {
        // 实现点赞逻辑
        LambdaQueryWrapper<UserPraise> eq = new QueryWrapper<UserPraise>().lambda()
                .eq(UserPraise::getSourceId, newsId)
                .eq(UserPraise::getSourceType,SourceTypeEnum.NEWS.getValue())
                .eq(UserPraise::getUserId, JwtTokenUtils.getUserInfoA().getUserId());
        if (userNewPraiseMapper.selectCount(eq) > 0){
            throw new APIException(ResultCodeEnum.ALREADY_EXIST);
        }
        userNewPraiseMapper.insert(new UserPraise(JwtTokenUtils.getUserInfoA().getUserId(),newsId, SourceTypeEnum.NEWS));
        return baseMapper.updatePraiseOrCollect(1,null,newsId) > 0;
    }

    @Override
    public Boolean cancelPraiseGameNews(Integer newsId) {
        LambdaQueryWrapper<UserPraise> eq = new QueryWrapper<UserPraise>().lambda()
                .eq(UserPraise::getSourceId, newsId)
                .eq(UserPraise::getSourceType,SourceTypeEnum.NEWS.getValue())
                .eq(UserPraise::getUserId, JwtTokenUtils.getUserInfoA().getUserId());
        // 实现取消点赞逻辑
        if (userNewPraiseMapper.selectCount(eq) == 0){
            throw new APIException(ResultCodeEnum.ALREADY_EXIST);
        }
        userNewPraiseMapper.delete(eq);
        return baseMapper.updatePraiseOrCollect(-1,null,newsId) > 0;
    }

    @Override
    public Boolean collectGameNews(Integer newsId) {
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        // 实现收藏逻辑
        baseMapper.updatePraiseOrCollect(null,1,newsId);
        return userCollectNewsMapper.insert(new UserCollectNews(userInfo.getUserId(),newsId,new Date())) > 0;

    }

    @Override
    public Boolean cancelCollectGameNews(Integer newsId) {
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        Integer count = userCollectNewsMapper.selectCount(new LambdaQueryWrapper<UserCollectNews>()
                .eq(UserCollectNews::getUserId, userInfo.getUserId())
                .eq(UserCollectNews::getNewId, newsId));
        if (count == 0){
            return true;
        }
        baseMapper.updatePraiseOrCollect(null,-1,newsId);
        // 实现取消收藏逻辑
        return userCollectNewsMapper.delete(new LambdaQueryWrapper<UserCollectNews>()
                .eq(UserCollectNews::getUserId, userInfo.getUserId())
                .eq(UserCollectNews::getNewId, newsId)) > 0;

    }

    @Override
    public Boolean commentGameNews(UserCommentNewParam param) {
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        GameNews gameNews = this.baseMapper.selectById(param.getNewId());
        if (gameNews == null) {
            throw new APIException(ResultCodeEnum.DATA_NOT_EXIST);
        }
        if (param.getCommentId() != null){
            UserComment userComment = userCommentMapper.selectById(param.getCommentId());
            if (userComment == null){
                throw new APIException(ResultCodeEnum.COMMENT_DATA_NOT_EXIST);
            }
        }
        UserComment userComment = new UserComment(param.getCommentId(), param.getNewId(), userInfo.getUserId(), param.getContent(),SourceTypeEnum.NEWS);
        return userCommentMapper.insert(userComment) > 0;
    }

    @Override
    public Boolean deleteCommentGameNews(Integer commentId) {
        UserComment userComment = userCommentMapper.selectById(commentId);
        if (userComment == null){
            throw new APIException(ResultCodeEnum.DATA_NOT_EXIST);
        }
        if (!userComment.getUserId().equals(JwtTokenUtils.getUserInfoA().getUserId())){
            throw new APIException(ResultCodeEnum.COMMENT_DELETE_ERROR);
        }
        return userCommentMapper.deleteById(commentId) > 0;
    }
}
